<!-- src/components/RangePicker/RangePicker.vue -->
<template>
  <div class="range-picker" :class="[rangeClass, { 'is-invalid': !validationState.valid }]">
    <!-- 输入框容器 -->
    <div class="range-inputs">
      <!-- 起始值输入插槽 -->
      <slot name="start-input">
        <input
            ref="startInput"
            type="text"
            :value="formattedStart"
            :placeholder="placeholderStart"
            :class="inputClass"
            :disabled="disabled"
            :readonly="readonly"
            @input="handleStartInput"
            @focus="handleFocus('start')"
            @blur="handleBlur"
            @keydown="handleKeyDown($event, 'start')"
            aria-label="范围选择起始值"
        >
      </slot>

      <!-- 分隔符插槽 -->
      <slot name="separator">
        <span class="separator">{{ separator }}</span>
      </slot>

      <!-- 结束值输入插槽 -->
      <slot name="end-input">
        <input
            ref="endInput"
            type="text"
            :value="formattedEnd"
            :placeholder="placeholderEnd"
            :class="inputClass"
            :disabled="disabled"
            :readonly="readonly"
            @input="handleEndInput"
            @focus="handleFocus('end')"
            @blur="handleBlur"
            @keydown="handleKeyDown($event, 'end')"
            aria-label="范围选择结束值"
        >
      </slot>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, toRefs } from 'vue';

const emit = defineEmits([
  'update:modelValue',
  'change',
  'start-change',
  'end-change',
  'validate',
  'focus',
  'blur',
  'keydown'
]);

const props = defineProps({
  modelValue: { type: [Object, Array], default: () => ({ start: null, end: null }) },
  min: { type: [Number, Date, String], default: null },
  max: { type: [Number, Date, String], default: null },
  step: { type: Number, default: 1 },
  allowSame: { type: Boolean, default: false },
  placeholderStart: { type: String, default: '请输入起始值' },
  placeholderEnd: { type: String, default: '请输入结束值' },
  format: { type: Function, default: value => value },
  disabled: { type: Boolean, default: false },
  readonly: { type: Boolean, default: false },
  required: { type: Boolean, default: false },
  validationRules: { type: Array, default: () => [] },
  inputClass: { type: [String, Array, Object], default: '' },
  separator: { type: String, default: '→' },
  rangeClass: { type: [String, Array, Object], default: '' }
});

// 模板引用
const startInput = ref(null);
const endInput = ref(null);

// 响应式状态
const internalValue = ref(normalizeValue(props.modelValue));
const isFocused = ref(false);
const validationState = ref({ valid: true, messages: [] });

// 格式化显示值
const formattedStart = computed(() => props.format(internalValue.value.start));
const formattedEnd = computed(() => props.format(internalValue.value.end));

// 值规范化处理
function normalizeValue(value) {
  if (Array.isArray(value)) {
    return { start: value[0], end: value[1] };
  }
  return { ...value };
}

// 输入处理
function handleStartInput(e) {
  const rawValue = e.target.value;
  internalValue.value.start = parseInput(rawValue);
  processValueChange('start');
}

function handleEndInput(e) {
  const rawValue = e.target.value;
  internalValue.value.end = parseInput(rawValue);
  processValueChange('end');
}

// 值解析（可根据实际需求扩展）
function parseInput(value) {
  // 此处实现具体解析逻辑，示例处理数字类型
  if (!isNaN(value)) return Number(value);
  return value;
}

// 处理值变化
function processValueChange(source) {
  // 自动交换逻辑
  if (shouldSwapValues()) {
    [internalValue.value.start, internalValue.value.end] =
        [internalValue.value.end, internalValue.value.start];
  }

  // 边界检查
  applyBoundaryConstraints();

  // 触发更新
  emitUpdate();
  runValidation();
  emitChangeEvent(source);
}

// 值交换判断
function shouldSwapValues() {
  if (props.allowSame) return false;
  return internalValue.value.start > internalValue.value.end;
}

// 应用边界限制
function applyBoundaryConstraints() {
  if (props.min !== null) {
    internalValue.value.start = Math.max(internalValue.value.start, props.min);
    internalValue.value.end = Math.max(internalValue.value.end, props.min);
  }
  if (props.max !== null) {
    internalValue.value.start = Math.min(internalValue.value.start, props.max);
    internalValue.value.end = Math.min(internalValue.value.end, props.max);
  }
}

// 事件触发
function emitUpdate() {
  const outputValue = Array.isArray(props.modelValue)
      ? [internalValue.value.start, internalValue.value.end]
      : { ...internalValue.value };

  emit('update:modelValue', outputValue);
}

function emitChangeEvent(source) {
  emit('change', internalValue.value);
  emit(`${source}-change`, internalValue.value[source]);
}

// 验证逻辑
function runValidation() {
  const messages = [];

  // 必填验证
  if (props.required && (!internalValue.value.start || !internalValue.value.end)) {
    messages.push('必须填写完整范围值');
  }

  // 自定义规则验证
  props.validationRules.forEach(rule => {
    const result = rule(internalValue.value);
    if (typeof result === 'string') messages.push(result);
  });

  validationState.value = {
    valid: messages.length === 0,
    messages
  };

  emit('validate', validationState.value);
}

// 暴露方法
function focusStart() {
  startInput.value?.focus();
}

function focusEnd() {
  endInput.value?.focus();
}

// 其他事件处理
function handleFocus(type) {
  isFocused.value = true;
  emit('focus', { type, value: internalValue.value });
}

function handleBlur() {
  isFocused.value = false;
  emit('blur', internalValue.value);
}

function handleKeyDown(e, type) {
  emit('keydown', { event: e, type });

  // 键盘导航增强
  const isNumber = typeof internalValue.value.start === 'number';
  if (isNumber) {
    const step = e.shiftKey ? props.step * 10 : props.step;
    switch(e.key) {
      case 'ArrowUp':
        internalValue.value[type] += step;
        processValueChange(type);
        e.preventDefault();
        break;
      case 'ArrowDown':
        internalValue.value[type] -= step;
        processValueChange(type);
        e.preventDefault();
        break;
    }
  }
}

// 值监听
watch(() => props.modelValue, (newVal) => {
  internalValue.value = normalizeValue(newVal);
});

defineExpose({ focusStart, focusEnd, validationState });
</script>

<style scoped>
.range-picker {
  --separator-color: #666;
  --input-border: 1px solid #ccc;
  --input-padding: 8px;
  display: inline-flex;
  min-width: 300px; /* 新增最小宽度 */
}

.range-inputs {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%; /* 确保宽度继承 */
}

input {
  padding: var(--input-padding);
  border: var(--input-border);
  border-radius: 4px;
  min-width: 120px; /* 输入框最小宽度 */
  flex: 1; /* 新增弹性布局 */
}

input:disabled {
  background-color: #eee;
  cursor: not-allowed;
}

.separator {
  color: var(--separator-color);
  padding: 0 4px;
}

.is-invalid input {
  border-color: #ff4444;
}
</style>